import os
import json
from pathlib import Path
from typing import Tuple

import nacl.signing
import nacl.encoding


class Arbiter:
    """Simple Arbiter that manages a signing keypair for session signing.

    Uses ed25519 via pynacl to sign session payloads. SK is stored locally in
    a file under the working directory by default.
    """

    def __init__(self, sk_path: str = "arbiter_sk.json"):
        self.sk_path = Path(sk_path)
        self._signing_key = None

    def setup(self) -> str:
        """Generates a new keypair, saves SK locally, and returns the public key (hex)."""
        signing_key = nacl.signing.SigningKey.generate()
        verify_key = signing_key.verify_key
        sk_hex = signing_key.encode(encoder=nacl.encoding.HexEncoder).decode()
        pk_hex = verify_key.encode(encoder=nacl.encoding.HexEncoder).decode()
        self._signing_key = signing_key
        self._save_sk(sk_hex)
        return pk_hex

    def _save_sk(self, sk_hex: str):
        data = {"sk": sk_hex}
        with open(self.sk_path, "w") as f:
            json.dump(data, f)

    def _load_sk(self):
        if self._signing_key is not None:
            return self._signing_key
        if not self.sk_path.exists():
            raise FileNotFoundError(f"SK file not found: {self.sk_path}")
        with open(self.sk_path, "r") as f:
            data = json.load(f)
        sk_hex = data["sk"]
        self._signing_key = nacl.signing.SigningKey(sk_hex, encoder=nacl.encoding.HexEncoder)
        return self._signing_key

    def sign_session(self, payload: bytes) -> str:
        """Sign a session payload and return signature hex."""
        sk = self._load_sk()
        sig = sk.sign(payload).signature
        return nacl.encoding.HexEncoder.encode(sig).decode()


def verify_session(pk_hex: str, payload: bytes, sig_hex: str) -> bool:
    """Verify a session signature given public key hex, payload, and signature hex."""
    try:
        pk = nacl.signing.VerifyKey(pk_hex, encoder=nacl.encoding.HexEncoder)
        sig = nacl.encoding.HexEncoder.decode(sig_hex)
        pk.verify(payload, sig)
        return True
    except Exception:
        return False
